package okl.tdf.components
{
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import spark.components.Label;
	
	/**
	 *  Component encapsulates duration since <code>targetTime</code>.
	 * 
	 *	<p>The duration is displayed as text formatted by <code></code> and invalidated every <code>invalidationInterval</code> millisecond</p>
	 * 
	 *	@author "oleksandr.kulinchenko@gmail.com"
	 */
	public class DurationLabel extends Label
	{
		public function DurationLabel()
		{
			super();
		}
		
		private var _timer:Timer;

		
		//{region CLASS_INTERFACE
		private var _invalidationInterval:Number=1000;

		/**
		 * Label should be invalidated every <code>invalidationInterval</code> ms
		 */
		public function get invalidationInterval():Number
		{
			return _invalidationInterval;
		}

		public function set invalidationInterval(value:Number):void
		{
			if(value==invalidationInterval)return;
			_invalidationInterval = value;
			resetInvalidationTimer();
		}
		
		private var _targetTime:Date;

		/**
		 * Date since duration text should be displayed
		 */
		public function get targetTime():Date
		{
			return _targetTime;
		}
		
		public function set targetTime(value:Date):void
		{
			if(value==targetTime)return;
			_targetTime = value;
			
			resetInvalidationTimer();
		}
		
		private var _labelFunction:Function=defaultLabelFunction;
		
		/**
		 * Function to format duration <code>myLabelFunction(timeDiff:Number):String</code>
		 * 
		 * Has default value
		 */
		public function get labelFunction():Function
		{
			return _labelFunction;
		}
		
		/**
		 * @private
		 */
		public function set labelFunction(value:Function):void
		{
			_labelFunction = value;
			invalidateTime();
		}
	
		//}endregion
		
		//{region INTER_LOGIC
		private function defaultLabelFunction(value:Number):String{
			return value.toString();
		}
		
		private function resetInvalidationTimer():void{
			if(_timer==null){
				_timer = new Timer(invalidationInterval);
				_timer.addEventListener(TimerEvent.TIMER, invalidateTime);
			}
			if(_timer.running)_timer.reset();
			_timer.start();
			invalidateTime();
		}
		
		/**
		 * Text invalidation - triggers life cycle update of display list
		 */
		private function invalidateTime(skipEvent:Event=null):void{
			if(targetTime==null){
				this.text="";
				return;
			}
			var now:Date = new Date();
			var timeDiff:Number = now.time-targetTime.time;
			this.text= labelFunction.call(this, timeDiff);
		}
		//}endregion

	}
}